#include "MiniLib.h"
#include <algorithm>
#include <cstdint>
#include <cstdio>
#include <cstring>
// #include <new>
#include <fstream>
#include <ios>
#include <list>
#include <string>
#include <sys/socket.h>
#include <sys/types.h>
#include <iostream>
#include <vector>
// #include <cstdarg>
// #include <cstdio>
// #include <cstdlib>

FILE *LogOut;

// HttpStrNode::HttpStrNode(const char *buf){
//     buff=new char[strlen(buf)+1];
//     strcpy(buff, buf);
// }

// HttpStrNode::~HttpStrNode(){
//     delete [] buff;
// }

// HttpStrList::~HttpStrList(){
//     HttpStrNode * tmp;
//     while (head->next != nullptr) {
//         tmp=head->next;
//         head->next=head->next->next;
//         delete tmp;
//     }
// }

uint16_t HttpReadLine(std::string &buff, uint32_t client_socket){
    // uint16_t rn=0;
    // uint8_t c=0,n=0;
    uint16_t index=0;
    char c;
    // char buf[1024];
    // while (c!='\n' && index<size) {
    //     n=recv(client_socket, &c, 1, 0);
    //     if(n>0){
    //         if(c=='\r'){
    //             n=recv(client_socket, &c, 1, MSG_PEEK);
    //             if(n>0 && c=='\n'){
    //                 recv(client_socket, &c, 1, 0);
    //             }else {
    //                 c='\n';
    //             }
    //         }
    //         buff[index]=c;
    //         index++;
    //     }else {
    //         break;
    //     }
    // }
    while ((recv(client_socket, &c, 1, 0))>0 && c!='\n') {
        if (c=='\r'){
            c='\n';
        }
        // buf[index]=c;
        buff+=c;
        index++;
    }
    // buf[index]='0';
    // buff=buf;
    return index;
}

bool notfound(uint32_t socket){
    std::string head="HTTP/1.1 404 Not Found\r\n";
    head+="Server:MiniHttpd/0.1\r\n";
    head+="Content-Type:text/html\r\n";
    head+="\r\n";
    head+="<h2>Not Found</h2>\r\n";

    send(socket, head.c_str(), head.size(), 0);
    return true;
}

uint16_t send2client(uint32_t socket,std::string &wpath){
    std::string text="HTTP/1.1 200 OK\r\n";
    // std::string head="HTTP/1.1 200 OK\r\n";
    // text+;
    // std::cout<<"again\n";
    // bool ok=false;
    std::string type;
    for(auto i=wpath.rbegin();i!=wpath.rend();i++){
        // if(ok){
        //     type+=(*i);
        // }
        if((*i)=='.'){
            break;
        }
        type+=(*i);
    }
    std::reverse(type.begin(),type.end());
    std::cout<<type<<std::endl;
    auto fmode=std::ios_base::in;
    if(type=="jpg"){
        type="image/jpeg";
        fmode|=std::ios_base::binary;
    }else if (type=="html") {
        type="text/html";
    }else if (type=="css") {
        type="text/css";
    }else if (type=="js") {
        type="text/javascript";
    }
    std::string src="\r";
    
    std::ifstream fsrc;
    fsrc.open(wpath,fmode);
    if(fsrc.is_open()==false){
        std::cout<<wpath<<"nofound"<<std::endl;
        notfound(socket);
        return 1;
    }
    // if(){

    // }
    // if((fmode &std::ios_base::binary) != std::ios_base::binary){
    //     for(char c='\n';c!=EOF;){
    //         src+=c;
    //         c=fsrc.get();
    //     }
    //     // src+='\n';
        std::string opath;
        if(type=="text/css"){
            opath="outcsss";
        }else if (type=="text/javascript") {
            opath="outjss";
        }else if (type=="text/html") {
            opath="outhtmll";
        }
        std::ofstream srco(opath);
        // srco<<src;
        // srco.close();
    //     fsrc.close();
    //     text+="Server:MiniHttpd/0.1\r\n";
    //     text+="Content-Type:";
    //     std::cout<<type<<std::endl;
    //     text+=type;
    // // std::cout<<text;
    //     text+="\r\n";
    //     text+="\r\n";
    // // std::cout<<text;
    //     text+=src;
    //     text+="\r\n";
    // // text+="\r\n";
    // // text+="\n";
    //     std::ofstream of1(opath+"all");
    //     of1<<text;
    //     of1.close();
    //     send(socket, text.c_str(), text.size(), 0);
    // }else{
        // std::cout<<"b文件\n";
        // src.clear();
        // std::vector<char> vec2;
        char c;
        uint64_t sizee=0;
        
        // fsrc.close();
        // while(fsrc.read(&c, 1)){
            
        //     // send(socket, &c, 1, 0);

        //     vec2.push_back(c);
        //     // if(c==EOF){
        //     //     break;
        //     // }
        // }
        // for(char c;c!=EOF;){
        //     c=fsrc.get();
        //     // vec2.push_back(c);
        // }
        
        // sizee-=1;
        // std::vector<char> vec2(sizee+1);
        // fsrc.seekg(std::ios::beg);
        // fsrc.read(vec2.data(), sizee+1);
        // std::ofstream srco("aaaout");
        // for(auto i:vec2){
        //     srco<<i;
        // }
        // srco<<fsrc;
        // srco.close();
        // fsrc.close();
        text+="Server:MiniHttpd/0.1\r\n";
        text+="Content-Type:";
        std::cout<<type<<std::endl;
        text+=type;
    // // std::cout<<text;
        text+="\r\n";
        text+="\r\n";
        std::ofstream of1("new.cphtml");
        of1<<text;
        of1.close();
        send(socket, text.c_str(), text.size(), 0);
        // send(socket,vec2.data(),vec2.size(),0);
        // text+="\r\n";
    // std::cout<<text;
        char bufff[1024];
        while (!fsrc.eof()) {
            // std::cout<<"1.1\n";
            fsrc.read(bufff,1024);
            send(socket, bufff, fsrc.gcount(), 0);
            srco.write(bufff, fsrc.gcount());
        }
        
    // }
    srco.close();
    // std::cout<<"传输完成\n";
    return 0;
}

int8_t InitMiniLog(){
    LogOut=fopen("./LogOut.txt", "a+");
    // printf("2\n");
    if(LogOut){
        fprintf(LogOut, "\n----------------------\n\n");
        MiniLog("MiniLog初始化成功");
        return 1;
    }
    // printf("3\n");
    fprintf(stderr,"MiniLog初始化失败\n");
    exit(1);
}

void ctrlc(int sig){
    fprintf(LogOut, "用户自行中断...");
    fprintf(stderr, "用户自行中断...");
    // MiniLog("用户自行中断...");
    CloseMiniLog();
    // fclose(LogOut);
    exit(1);
}

void CloseMiniLog(){
    fprintf(LogOut,"\n----------------------\n\n");
    fclose(LogOut);
}

// class MiniLoop {
//     MiniLoop();
// };

void vfMiniLog(FILE *where, const char *fmt, va_list args) {
    char *ffmt =(char *)malloc((strlen(fmt) + 1) + (strlen("Mini INFO: ") + 1));
    time_t ltime=time(NULL);
    struct tm *tm1=localtime(&ltime);
    // printf("%p\n",tm1);
    char tfmt[30];
    strftime(tfmt, 29, "%Y-%m-%d %X", tm1);
    // vsprintf(ffmt, fmt, args);
    // printf("%p\n",tm1);
    strcpy(ffmt, "Mini INFO: ");
    strcat(ffmt, fmt);
    // va_list args;
    // va_start(args, fmt);
    
    vfprintf(where, ffmt, args);
    fprintf(where, "  --  %s",tfmt);
    // fputs(tfmt, where);
    fputc('\n',where);
    free(ffmt);
    // free(tm1);
    // va_end(args);
}

void fMiniLog(FILE *where, const char *fmt, ...) {
    va_list args;
    va_start(args, fmt);
    vfMiniLog(where, fmt, args);
    va_end(args);
}

void MiniLog(const char *fmt, ...) {
    // char *ffmt = (char *)malloc((strlen(fmt)+1)+(strlen("Mini INFO:
    // ")+1)); strcpy(ffmt, "Mini INFO: "); strcat(ffmt, fmt);
    va_list args;
    va_start(args, fmt);
    // vprintf(ffmt,args);
    // fputs(fmt,stderr);
    vfMiniLog(stdout,fmt,args);
    // vfprintf(stdout, fmt, args);
    // 
    // fputs(fmt,stderr);
    // vfMiniLog(LogOut,fmt,args);
    // putchar('\n');
    va_end(args);

    va_start(args, fmt);
    vfMiniLog(LogOut,fmt,args);
    // vfprintf(LogOut, fmt, args);
    va_end(args);
}

void MiniError(const char *fmt, ...) {
    // char *ffmt = (char *)malloc((strlen(fmt)+1)+(strlen("Mini INFO:
    // ")+1)); strcpy(ffmt, "Mini INFO: "); strcat(ffmt, fmt);
    va_list args;
    va_start(args, fmt);
    // vfprintf(stderr,ffmt,args);
    vfMiniLog(stderr, fmt, args);
    // putchar('\n');
    va_end(args);
}

// void MiniLogf(const char *fmt, ...){
//     va_list args;
//     va_start(args, fmt);
//     vfMiniLog(MiniLog,fmt,args);
//     va_end(args);
// }